home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2001 December / pcwk12201b.iso / Wersje pelne i specjalne / Winamp 2.77 i 3.0beta / wasabi-sdk_beta1.exe / jnetlib / asyncdns.cpp next >
C/C++ Source or Header  |  2001-10-08  |  7KB  |  291 lines

  1. /*
  2.  
  3.   Nullsoft WASABI Source File License
  4.  
  5.   Copyright 1999-2001 Nullsoft, Inc.
  6.  
  7.     This software is provided 'as-is', without any express or implied
  8.     warranty.  In no event will the authors be held liable for any damages
  9.     arising from the use of this software.
  10.  
  11.     Permission is granted to anyone to use this software for any purpose,
  12.     including commercial applications, and to alter it and redistribute it
  13.     freely, subject to the following restrictions:
  14.  
  15.     1. The origin of this software must not be misrepresented; you must not
  16.        claim that you wrote the original software. If you use this software
  17.        in a product, an acknowledgment in the product documentation would be
  18.        appreciated but is not required.
  19.     2. Altered source versions must be plainly marked as such, and must not be
  20.        misrepresented as being the original software.
  21.     3. This notice may not be removed or altered from any source distribution.
  22.  
  23.  
  24.   Brennan Underwood
  25.   brennan@nullsoft.com
  26.  
  27. */
  28.  
  29. /*
  30. ** JNetLib
  31. ** Copyright (C) 2000-2001 Nullsoft, Inc.
  32. ** Author: Justin Frankel
  33. ** File: asyncdns.cpp - JNL portable asynchronous DNS implementation
  34. ** License: see jnetlib.h
  35. */
  36.  
  37. #include "netinc.h"
  38. #include "util.h"
  39. #include "asyncdns.h"
  40.  
  41. JNL_AsyncDNS::JNL_AsyncDNS(int max_cache_entries)
  42. {
  43.   m_thread_kill=1;
  44.   m_thread=0;
  45.   m_cache_size=max_cache_entries;
  46.   m_cache=(cache_entry *)::malloc(sizeof(cache_entry)*m_cache_size);
  47.   memset(m_cache,0,sizeof(cache_entry)*m_cache_size);
  48. }
  49.  
  50. JNL_AsyncDNS::~JNL_AsyncDNS()
  51. {
  52. #ifndef NO_DNS_SUPPORT
  53.   m_thread_kill=1;
  54.  
  55. #ifdef _WIN32
  56.   if (m_thread)
  57.   {
  58.     WaitForSingleObject(m_thread,INFINITE);
  59.     CloseHandle(m_thread);
  60.   }
  61. #else
  62.   if (m_thread)
  63.   {
  64.     void *p;
  65.     pthread_join(m_thread,&p);
  66.   }
  67. #endif//!_WIN32
  68. #endif//NO_DNS_SUPPORT
  69.   free(m_cache);
  70. }
  71.  
  72. #ifdef _WIN32
  73. unsigned long WINAPI JNL_AsyncDNS::_threadfunc(LPVOID _d)
  74. #else
  75. unsigned int JNL_AsyncDNS::_threadfunc(void *_d)
  76. #endif
  77. {
  78. #ifndef NO_DNS_SUPPORT
  79.   int nowinsock=JNL::open_socketlib();
  80.   JNL_AsyncDNS *_this=(JNL_AsyncDNS*)_d;
  81.   int x;
  82.   for (x = 0; x < _this->m_cache_size && !_this->m_thread_kill; x ++)
  83.   {
  84.     if (_this->m_cache[x].last_used && !_this->m_cache[x].resolved)
  85.     {
  86.       if (!nowinsock) 
  87.       {
  88.         if (_this->m_cache[x].mode==0)
  89.         {
  90.           struct hostent *hostentry;
  91.           hostentry=::gethostbyname(_this->m_cache[x].hostname);
  92.           if (hostentry)
  93.           {
  94.             _this->m_cache[x].addr=*((int*)hostentry->h_addr);
  95.           }
  96.           else
  97.             _this->m_cache[x].addr=INADDR_NONE;
  98.         }
  99.         else if (_this->m_cache[x].mode==1)
  100.         {
  101.           struct hostent *ent;
  102.           ent=::gethostbyaddr((const char *)&_this->m_cache[x].addr,4,AF_INET);
  103.           if (ent)
  104.           {
  105.             strncpy(_this->m_cache[x].hostname,ent->h_name,255);
  106.             _this->m_cache[x].hostname[255]=0;
  107.           }
  108.           else
  109.           {
  110.             _this->m_cache[x].hostname[0]=0;
  111.           }
  112.         }
  113.         _this->m_cache[x].resolved=1;
  114.       }
  115.       else
  116.       {
  117.         if (_this->m_cache[x].mode==0)
  118.         {
  119.           _this->m_cache[x].addr=INADDR_NONE;
  120.           _this->m_cache[x].resolved=1;
  121.         }
  122.         else if (_this->m_cache[x].mode==1)
  123.         {
  124.           _this->m_cache[x].hostname[0]=0;
  125.           _this->m_cache[x].resolved=1;
  126.         }
  127.       }
  128.     }
  129.   }
  130.   if (!nowinsock) JNL::close_socketlib();
  131.   _this->m_thread_kill=1;
  132. #endif // NO_DNS_SUPPORT
  133.  
  134.   return 0;
  135. }
  136.  
  137. int JNL_AsyncDNS::resolve(char *hostname, unsigned long *addr)
  138. {
  139.   // return 0 on success, 1 on wait, -1 on unresolvable
  140.   int x;
  141.   unsigned long ip=inet_addr(hostname);
  142.   if (ip != INADDR_NONE) 
  143.   {
  144.     *addr=ip;
  145.     return 0;
  146.   }
  147. #ifndef NO_DNS_SUPPORT
  148.  
  149.   for (x = 0; x < m_cache_size; x ++)
  150.   {
  151.     if (!strcasecmp(m_cache[x].hostname,hostname) && m_cache[x].mode==0)
  152.     {
  153.       m_cache[x].last_used=time(NULL);
  154.       if (m_cache[x].resolved)
  155.       {
  156.         if (m_cache[x].addr == INADDR_NONE)
  157.         {
  158.           return -1;
  159.         }
  160.         struct in_addr in;
  161.         in.s_addr=m_cache[x].addr;
  162.         *addr=m_cache[x].addr;
  163.         return 0;
  164.       }
  165.       makesurethreadisrunning();
  166.       return 1;
  167.     }
  168.   }
  169.   // add to resolve list
  170.   int oi=-1;
  171.   for (x = 0; x < m_cache_size; x ++)
  172.   {
  173.     if (!m_cache[x].last_used)
  174.     {
  175.       oi=x;
  176.       break;
  177.     }
  178.     if ((oi==-1 || m_cache[x].last_used < m_cache[oi].last_used) && m_cache[x].resolved)
  179.     {
  180.       oi=x;
  181.     }
  182.   }
  183.   if (oi == -1)
  184.   {
  185.     return -1;
  186.   }
  187.   strcpy(m_cache[oi].hostname,hostname);
  188.   m_cache[oi].mode=0;
  189.   m_cache[oi].addr=INADDR_NONE;
  190.   m_cache[oi].resolved=0;
  191.   m_cache[oi].last_used=time(NULL);
  192.  
  193.   makesurethreadisrunning();
  194.   return 1;
  195. #else
  196.   return -1;
  197. #endif
  198. }
  199.  
  200. int JNL_AsyncDNS::reverse(unsigned long addr, char *hostname)
  201. {
  202.   // return 0 on success, 1 on wait, -1 on unresolvable
  203.   int x;
  204.   if (addr == INADDR_NONE) 
  205.   {
  206.     return -1;
  207.   }
  208. #ifndef NO_DNS_SUPPORT
  209.   for (x = 0; x < m_cache_size; x ++)
  210.   {
  211.     if (m_cache[x].addr==addr && m_cache[x].mode==1)
  212.     {
  213.       m_cache[x].last_used=time(NULL);
  214.       if (m_cache[x].resolved)
  215.       {
  216.         if (!m_cache[x].hostname[0])
  217.         {
  218.           return -1;
  219.         }
  220.         strncpy(hostname,m_cache[x].hostname,255);
  221.         hostname[255]=0;
  222.         return 0;
  223.       }
  224.       makesurethreadisrunning();
  225.       return 1;
  226.     }
  227.   }
  228.   // add to resolve list
  229.   int oi=-1;
  230.   for (x = 0; x < m_cache_size; x ++)
  231.   {
  232.     if (!m_cache[x].last_used)
  233.     {
  234.       oi=x;
  235.       break;
  236.     }
  237.     if ((oi==-1 || m_cache[x].last_used < m_cache[oi].last_used) && m_cache[x].resolved)
  238.     {
  239.       oi=x;
  240.     }
  241.   }
  242.   if (oi == -1)
  243.   {
  244.     return -1;
  245.   }
  246.   m_cache[oi].addr=addr;
  247.   m_cache[oi].hostname[0]=0;
  248.   m_cache[oi].resolved=0;
  249.   m_cache[oi].mode=1;
  250.   m_cache[oi].last_used=time(NULL);
  251.  
  252.   makesurethreadisrunning();
  253.   return 1;
  254. #else
  255.   return -1;
  256. #endif
  257. }
  258.  
  259.  
  260. void JNL_AsyncDNS::makesurethreadisrunning(void)
  261. {
  262. #ifndef NO_DNS_SUPPORT
  263.   if (m_thread_kill)
  264.   {
  265.   #ifdef _WIN32
  266.     if (m_thread)
  267.     {
  268.       WaitForSingleObject(m_thread,INFINITE);
  269.       CloseHandle(m_thread);
  270.     }
  271.     DWORD id;
  272.     m_thread_kill=0;
  273.     m_thread=CreateThread(NULL,0,_threadfunc,(LPVOID)this,0,&id);
  274.     if (!m_thread)
  275.     {
  276.   #else
  277.     if (m_thread)
  278.     {
  279.       void *p;
  280.       pthread_join(m_thread,&p);
  281.     }
  282.     m_thread_kill=0;
  283.     if (pthread_create(&m_thread,NULL,(void *(*) (void *))_threadfunc,(void*)this) != 0)
  284.     {
  285.   #endif
  286.       m_thread_kill=1;
  287.     }
  288.   }
  289. #endif//NO_DNS_SUPPORT
  290. }
  291.